package com.ruicar.afs.cloud.channel.mange.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.channel.common.until.ChannelConfig;
import com.ruicar.afs.cloud.channel.mange.entity.ChannelAppertainRegion;
import com.ruicar.afs.cloud.channel.mange.entity.ChannelUser;
import com.ruicar.afs.cloud.channel.mange.entity.ChannelUserAppertain;
import com.ruicar.afs.cloud.channel.mange.entity.UserRegion;
import com.ruicar.afs.cloud.channel.mange.enums.IsParentEnum;
import com.ruicar.afs.cloud.channel.mange.enums.RegionLevel;
import com.ruicar.afs.cloud.channel.mange.service.ChannelAppertainRegionService;
import com.ruicar.afs.cloud.channel.mange.service.ChannelUserAppertainService;
import com.ruicar.afs.cloud.channel.mange.service.ChannelUserService;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.log.annotation.SysLog;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xudongdong
 * @date 2020-06-04
 */
@RestController
@AllArgsConstructor
@RequestMapping("/appertainRegion")
@Api(value = "appertainRegion", description = "所属区域信息")
public class ChannelAppertainRegionController {

    private final ChannelAppertainRegionService appertainRegionService;
    private final ChannelConfig channelConfig;
    private final ChannelUserAppertainService userAppertainService;
    private final ChannelUserService userService;



    @PostMapping("/getByParentId/{parentId}")
    @ApiOperation(value = "通过id获取")
    public IResponse<List<ChannelAppertainRegion>> getByParentId(@PathVariable String parentId) {
        return new IResponse<List<ChannelAppertainRegion>>().setData(setInfo(appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query()
                .lambda().eq(ChannelAppertainRegion::getParentId, parentId).orderByAsc(ChannelAppertainRegion::getSortOrder))));
    }

    @PostMapping("/getAll/{ids}")
    @ApiOperation(value = "通过id获取")
    public IResponse<List<ChannelAppertainRegion>> getAll(@PathVariable Long[] ids) {
        List<ChannelAppertainRegion> appertainRegionList = setInfo(appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query()));
        List<ChannelAppertainRegion> appertainRegionLists = JSONUtil.parseArray(appertainRegionList).toList(ChannelAppertainRegion.class);
        for (ChannelAppertainRegion v1 : appertainRegionLists) {
            for (Long v2 : ids) {
                if (v1.getId().equals(v2)) {
                    v1.setSelected(true);
                }
            }
        }
        Map<Long, List<ChannelAppertainRegion>> collect = appertainRegionLists.stream().collect(Collectors.groupingBy(ChannelAppertainRegion::getParentId));
        List<ChannelAppertainRegion> list = collect.get(0L);
        if (ObjectUtils.isNotEmpty(list)) {
            list.forEach(en -> forEach(collect, en));
        }
        return new IResponse<List<ChannelAppertainRegion>>().setData(list);
    }

    private static void forEach(Map<Long, List<ChannelAppertainRegion>> collect, ChannelAppertainRegion entity) {
        List<ChannelAppertainRegion> treeMenuNodes = collect.get(entity.getId());
        if (collect.get(entity.getId()) != null) {
            //排序
            entity.setChildren(treeMenuNodes);
            entity.getChildren().forEach(t -> {
                forEach(collect, t);
            });
        }
    }

    @PostMapping("/add")
    @ApiOperation(value = "添加")
    @SysLog("所属区域")
    @Transactional
    public IResponse<Boolean> add(@RequestBody ChannelAppertainRegion appertainRegion) {
        if(RegionLevel.REGION_LEVEL_ONE.equals(appertainRegion.getLevel().toString())){
            List<ChannelAppertainRegion> list=appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query().lambda().eq(ChannelAppertainRegion::getLevel,RegionLevel.REGION_LEVEL_ONE.toString()));
            if(list.size()>0){
                throw new AfsBaseException("已存在一级区域！");
            }
        }
        appertainRegion.setIsParent(IsParentEnum.NO.getValue());
        appertainRegionService.save(appertainRegion);
        ChannelAppertainRegion appertainRegions = appertainRegionService.getById(appertainRegion.getParentId());
        if (appertainRegions != null && IsParentEnum.NO.getValue().equals(appertainRegions.getIsParent())) {
            appertainRegions.setIsParent(IsParentEnum.YES.getValue());
            appertainRegionService.updateById(appertainRegions);
        }
        return new IResponse<Boolean>().setMsg("添加成功").setData(true);
    }

    @PostMapping("/edit")
    @ApiOperation(value = "编辑")
    @SysLog("编辑所属区域")
    @Transactional
    public IResponse<Boolean> edit(@RequestBody ChannelAppertainRegion appertainRegion) {
        appertainRegionService.updateById(appertainRegion);
        return new IResponse<Boolean>().setMsg("编辑成功").setData(true);
    }

    @RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
    @ApiOperation(value = "批量通过id删除")
    @SysLog("批量通过id删除所属区域")
    @Transactional
    public IResponse<Boolean> delByIds(@PathVariable String[] ids) {

        Arrays.stream(ids).forEach(id -> {
            appertainRegionService.remove(Wrappers.<ChannelAppertainRegion>update().lambda().eq(ChannelAppertainRegion::getParentId, id));
            appertainRegionService.removeById(id);
        });

        return new IResponse<Boolean>().setMsg("批量通过id删除数据成功").setData(true);
    }

    @PostMapping("/search")
    @ApiOperation(value = "区域名模糊搜索")
    public IResponse<List<ChannelAppertainRegion>> searchByTitle(@RequestParam String title) {
        List<ChannelAppertainRegion> list = appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query().lambda().
                like(ChannelAppertainRegion::getTitle, title).orderByAsc(ChannelAppertainRegion::getSortOrder));
        list = setInfo(list);
        return new IResponse<List<ChannelAppertainRegion>>().setData(list);
    }

    public List<ChannelAppertainRegion> setInfo(List<ChannelAppertainRegion> list) {

        // lambda表达式
        list.forEach(item -> {
            if (!CommonConstants.PARENT_ID.equals(Long.valueOf(item.getParentId()))) {
                ChannelAppertainRegion parent = appertainRegionService.getById(item.getParentId());
                if (parent != null) {
                    item.setParentTitle(parent.getTitle());
                } else {
                    item.setParentTitle("一级部门");
                }
            } else {
                item.setParentTitle("一级部门");
            }
        });
        return list;
    }


    @PostMapping("/getAreaByParentId/{parentId}")
    @ApiOperation(value = "通过id获取")
    public IResponse<List<ChannelAppertainRegion>> getAreaByParentId(@PathVariable String parentId) {
        List<ChannelAppertainRegion> list =setInfo(appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query()
                .lambda().eq(ChannelAppertainRegion::getParentId, parentId).orderByAsc(ChannelAppertainRegion::getSortOrder)));

        if(!"0".equals(parentId)){
            ChannelAppertainRegion apper =appertainRegionService.getById(parentId);
            if("2".equals(apper.getLevel().toString())){
                // 说明这个是查出来省级别  要查本季和下级
                if(list.size()>0){
                    for (int i=0;i<list.size();i++){
                        // 查询出来所有 本级和下级的id
                        Set<Long> ids =new HashSet<>();
                        Set<Long> userIds =new HashSet<>();

                        ids.add(list.get(i).getId());
                        // 查询市级别的信息
                        List<ChannelAppertainRegion> clist =setInfo(appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query()
                                .lambda().eq(ChannelAppertainRegion::getParentId, list.get(i).getId()).orderByAsc(ChannelAppertainRegion::getSortOrder)));
                        if(clist.size()>0){
                            for (ChannelAppertainRegion c:clist ) {
                                ids.add(c.getId());
                            }
                            // 查询下面所有带的用户
                            List<ChannelUserAppertain> user =userAppertainService.list(Wrappers.<ChannelUserAppertain>query().lambda().in(ChannelUserAppertain::getAppertainRegionId,ids));
                            if(user.size()>0){

                                for (ChannelUserAppertain u:user ) {
                                    userIds.add(u.getUserId());
                                }
                            }
                        }
                        //   最后查询用户 然后赋值
                        if(userIds.size()>0){
                            List<ChannelUser> channelUsers =userService.list(Wrappers.<ChannelUser>query().lambda().in(ChannelUser::getUserId,userIds));
                            if(channelUsers.size()>0){
                                String areaUser ="";
                                for (ChannelUser cu:channelUsers ) {
                                    if(areaUser==""){
                                        areaUser=areaUser+cu.getUserRealName();
                                    }else {
                                        areaUser=areaUser+","+cu.getUserRealName();
                                    }

                                }
                                list.get(i).setTitle(list.get(i).getTitle()+"("+areaUser+")");
                            }
                        }
                    }
                }

            }else {
                // 查询区域有没有用户
                if(list.size()>0){
                    for (int j=0;j<list.size();j++){
                        Set<Long> userIds =new HashSet<>();
                        // 查询这个区域的用户
                        List<ChannelUserAppertain> user =userAppertainService.list(Wrappers.<ChannelUserAppertain>query().lambda().in(ChannelUserAppertain::getAppertainRegionId,list.get(j).getId()));
                        if(user.size()>0){
                            for (ChannelUserAppertain u:user ) {
                                userIds.add(u.getUserId());
                            }

                            List<ChannelUser> cUser =userService.list(Wrappers.<ChannelUser>query().lambda().in(ChannelUser::getUserId,userIds));
                            if(cUser.size()>0){
                                String areaUser ="";
                                for (ChannelUser cu:cUser ) {
                                    if(areaUser==""){
                                        areaUser=cu.getUserRealName();
                                    }else {
                                        areaUser=areaUser+","+cu.getUserRealName();
                                    }
                                }
                                list.get(j).setTitle(list.get(j).getTitle()+"("+areaUser+")");
                            }
                        }
                    }
                }
            }
        }
        return new IResponse<List<ChannelAppertainRegion>>().setData(list);
    }


    @PostMapping("/getUserByParentId/{parentId}")
    @ApiOperation(value = "通过id获取")
    public IResponse<List<UserRegion>> getUserByParentId(@PathVariable String parentId) {
        List<UserRegion> list=new ArrayList<>();
        // 根据id 查大区
        ChannelAppertainRegion fRegion=appertainRegionService.getById(parentId);
        Set<Long> allUserIds =new HashSet<>();
        if(RegionLevel.REGION_LEVEL_ONE.equals(fRegion.getLevel().toString())){
            // 说明我要展示第二个层级了
            // 先查询所有的二级好不好
            List<Long> regionIds=new ArrayList<>();
            List<ChannelAppertainRegion> li=appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query()
                    .lambda().eq(ChannelAppertainRegion::getParentId, parentId).orderByAsc(ChannelAppertainRegion::getSortOrder));
            if(li.size()>0){
                for (ChannelAppertainRegion l:li) {
                    ChannelUserAppertain appertain =userAppertainService.getOne(Wrappers.<ChannelUserAppertain>query().lambda().eq(ChannelUserAppertain::getAppertainRegionId,l.getId()));
                    UserRegion  ur =new UserRegion();
                    BeanUtils.copyProperties(l, ur);
                    if(appertain==null){
                        ur.setUserId(Long.valueOf(-1).toString());
                    }else {
                        ur.setUserId(appertain.getUserId().toString());
                    }
                    Set<Long> lower  =new HashSet<>();
                    this.user(lower,l.getId().toString());
                    if(lower.size()>0){
                        ur.setIsParent("1");
                    }else {
                        ur.setIsParent("0");
                    }
                    ur.setLowerUserIds(lower);
                    list.add(ur);
                }

            }else {
                return new IResponse<List<UserRegion>>().setData(list);
            }

        }else {
            this.user(allUserIds,parentId);
            for (Long l: allUserIds) {
                UserRegion  ur =new UserRegion();
                ur.setLevel(3);
                ur.setUserId(l.toString());
                list.add(ur);
            }
        }
        // 再次遍历赋值用户
        List<ChannelUser> user =userService.list();
        for(int i =0; i<list.size();i++){
            for(int j=0;j<user.size();j++){
                System.out.println("id"+list.get(i).getUserId().toString());
                if("-1".equals(list.get(i).getUserId().toString())){
                    list.get(i).setTitle("未定义"+"("+list.get(i).getTitle()+")");
                    break;
                }else {
                    if(list.get(i).getUserId().toString().equals(user.get(j).getUserId().toString())){
                        if(list.get(i).getLevel()!=null){
                            if(list.get(i).getTitle()!=null){
                                list.get(i).setTitle(user.get(j).getUserRealName()+"("+list.get(i).getTitle()+")");
                                break;
                            }else {
                                list.get(i).setTitle(user.get(j).getUserRealName());
                                break;
                            }

                        }else {
                            list.get(i).setTitle(user.get(j).getUserRealName());
                            break;
                        }
                    }
                }
            }
        }
        return new IResponse<List<UserRegion>>().setData(list);
    }

    public void user (Set<Long> allUserIds,String parentId){
        // 说明展示的第三层，那么 level 就是 3和4的
        List<Long> threeRegion =new ArrayList<>();
        Set<Long> allIds =new HashSet<>();
        // 这个是查出来所有的归属第二级的第三级数据
        List<ChannelAppertainRegion> li=appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query()
                .lambda().eq(ChannelAppertainRegion::getParentId, parentId));
        if(li.size()>0){
            for (ChannelAppertainRegion l:li ) {
                threeRegion.add(l.getId());
                allIds.add(l.getId());
            }
            List<ChannelAppertainRegion> fe=appertainRegionService.list(Wrappers.<ChannelAppertainRegion>query()
                    .lambda().in(ChannelAppertainRegion::getParentId, threeRegion));
            if(fe.size()>0){
                for (ChannelAppertainRegion f:fe) {
                    allIds.add(f.getId());
                }
            }
            // 查询出来用户的id
            if(allIds.size()>0){
                List<ChannelUserAppertain> appertain =userAppertainService.list(Wrappers.<ChannelUserAppertain>query().lambda().in(ChannelUserAppertain::getAppertainRegionId,allIds));
                if(appertain.size()>0){
                    for (ChannelUserAppertain u: appertain ) {
                        allUserIds.add(u.getUserId());
                    }
                }
            }

        }
    }
}
